from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.contrib.auth import authenticate, login as django_login, logout as django_logout
from django.contrib.auth.decorators import login_required
from datetime import date, timedelta, datetime
from dlog.dlogcore.models import *
from django.core import template_loader
from django.template import Context


def rget(request, frm, default):
    if request.has_key(frm):
        return request[frm]
    return default

def check_login_right(request):
    return request.user and request.user.is_authenticated()

def check_owener_right(request, item):
    return check_login_right(request) and item.create_by.id == request.user.id

def check_user_right(request, user):
    return check_login_right(request) and user.id == request.user.id

def stayPreAddress(request):
    try:
        if request.META.has_key('HTTP_REFERER'):
            return request.META['HTTP_REFERER']
    except:
        return "/dlog/"
    else:
        return "/dlog/"

def monthList(dt):
    ls = []
    for day in range(33):
        d = dt + timedelta(1) * day
        if dt.month != d.month:
            return ls
        ls.append(d)

def IsWorkDay(dt):
    return dt.weekday() != 5 and dt.weekday() != 6

def DiffWorkDay(dt, diff):
    dt = dt + timedelta(diff)
    while not IsWorkDay(dt):
        dt = dt + timedelta(diff)
    return dt

def setFlash(request, flash, succ=False):
    request.session['flash'] = {'succ':succ, 'flash':flash}
    
def doFlash(request):
    flash = request.session.get('flash', None)
    if flash: del request.session['flash']
    return flash

def _getlog_by_user(user, logs):
    for log in logs:
        if log.create_by.id == user.id: return log
    return None

def _getlog_by_date(dt, logs):
    for log in logs:
        if log.create_at.date() == dt: return log
    return None

def getLogsSomeday(dt):
    return DlogIssue.objects.filter(create_at__day=dt.day).filter(create_at__month=dt.month).filter(create_at__year=dt.year)

def getLogsSomeMonth(dt):
    return DlogIssue.objects.filter(create_at__month=dt.month).filter(create_at__year=dt.year)

def getLogSomedaySomeUser(dt, user):
    logs = getLogsSomeday(dt)
    return _getlog_by_user(user, logs)

def getBlackList():
    td = DiffWorkDay(date.today(), -1)
    bl = BlackListIssue.objects.filter(create_at__year=td.year).filter(create_at__month=td.month).filter(create_at__day=td.day)
    if bl and bl.count():
        return [User.objects.get(id=uid) for uid in bl[0].getList()]
    return None

def createBlackList():
    users = User.objects.filter(is_staff=False)
    tdlogs = getLogsSomeday(date.today())
    bl_users = [user for user in users if not _getlog_by_user(user, tdlogs)]
    bl = BlackListIssue()
    bl.setList([user.id for user in bl_users])
    bl.save()
    return bl_users

def do_sendreport(blacklists):
    from django.core.mail import send_mail
    send_from = 'dyl@kingsoft.net'
    for black_list in blacklists:
        try:
            report_subject = "工作日志日报 - %s" % black_list.create_at
            recipient_list = ['duanyuluo@kingsoft.com']
            t = template_loader.get_template('report.html')
            users = None
            if len(black_list.getList()):
                users = [User.objects.get(id=uid) for uid in black_list.getList()]
                for user in users:
                    recipient_list.append(user.email)
            ctx = Context({"blacklist":black_list, "users":users,
                           "send_from":send_from, "recipient_list":recipient_list})
            mail_content = t.render(ctx)
            send_mail(report_subject, mail_content, send_from, recipient_list, fail_silently=False)
        except Exception, e:
            raise e
        else:
            if not black_list.report_sended:
                black_list.report_sended = 1
                black_list.save()

def try_sendreport():
    blacklists = BlackListIssue.objects.filter(report_sended=0)
    do_sendreport(blacklists)

def getUserFirstComment(user):
    comms = CommentIssue.objects.filter(target__create_by=user).filter(readed=False).order_by('create_at')
    return comms.count() and comms[0] or None

def globalRenderOption(request, op):
    op['flash'] = doFlash(request)
    op['loginuser'] = request.user
    todos = SysNofifyIssue.objects.filter(ntype=SysNofifyIssue.TODO).order_by('-create_at')
    announces = SysNofifyIssue.objects.exclude(ntype=SysNofifyIssue.TODO).order_by('-create_at')
    op['announces'] = announces[:5]
    op['all_announces'] = announces
    op['todos'] = todos[:5]
    now = datetime.now()
    op['now'] = now
    op['blacklist'] = getBlackList()
    op['dlog_js_ver'] = '070309'
    if check_login_right(request):
        op['first_message'] = getUserFirstComment(request.user)
    return op

#==============================

def list(request):
    page = max(1, int(rget(request, "page", 1)))
    per_page = min(50, int(rget(request, "per_page", 10)))
    all = DlogIssue.objects.all().order_by('-id')
    issues = all[(page-1) * per_page : page * per_page - 1]
    op = globalRenderOption(request, {'issues':issues, 'page':page, 'per_page':per_page})
    if page > 1 : op['pre'] = page - 1
    if all.count() > page * per_page : op['next'] = page + 1
    return render_to_response('list.html', op)

def item(request, itemid):
    thisitem = DlogIssue.objects.get(id=itemid)
    if not thisitem:
        setFlash(request, "没有这条日志存在。")
        return HttpResponseRedirect(stayPreAddress(request))
    dt = thisitem.create_at.date()
    yest_log = getLogSomedaySomeUser(DiffWorkDay(dt, -1), thisitem.create_by)
    op = {'item':thisitem, 'yestoday':yest_log}
    comments = CommentIssue.objects.filter(target__id=itemid)
    if comments:
        if check_owener_right(request, thisitem):
            for comm in comments:
                if not comm.readed:
                    comm.readed = True
                    comm.save()
        op['comments'] = comments
    op['page_track_addr'] = '/dlog/item/id/'
    return render_to_response('item.html', globalRenderOption(request, op))
    
def add(request):
    if not check_login_right(request):
        setFlash(request, "请登录后再创建新日志")
        return HttpResponseRedirect("/dlog/login/?next=%s" % '/dlog/add/')
    dt = None
    if request.has_key('y') and request.has_key('m') and request.has_key('d'):
        dt = date(int(request['y']), int(request['m']), int(request['d']))
    else:
        dt = date.today()
    logs = getLogsSomeday(dt)
    log = _getlog_by_user(request.user, logs)
    if log:
        setFlash(request, "你已经新建了今天的日志，想修改他么？", True)
        return HttpResponseRedirect("/dlog/modify/%s/" % log.id)
    yestoday = getLogSomedaySomeUser(DiffWorkDay(dt, -1), request.user)
    op = {'yestoday':yestoday, 'cdate':dt}
    return render_to_response('add.html', globalRenderOption(request, op))
    
def do_add(request):
    newItem = DlogIssue()
    dt = None
    if request.has_key('y') and request.has_key('m') and request.has_key('d'):
        dt = datetime(int(request['y']), int(request['m']), int(request['d']))
    else:
        dt = datetime.now()
    newItem.create_at = dt
    newItem.content = request['content']
    newItem.plan = request['plan']
    newItem.create_by = request.user
    newItem.save()
    return HttpResponseRedirect("/dlog/item/%s" % newItem.id)

def delete(request, itemid):
    thisitem = DlogIssue.objects.get(id=itemid)
    if not check_owener_right(request, thisitem):
        setFlash(request, "只有所有者才能删除，请登录")
        return HttpResponseRedirect(stayPreAddress(request))
    thisitem.delete()
    next = stayPreAddress(request)
    if request.has_key('next'):
        next = request['next']
    return HttpResponseRedirect(next)

def modify(request, itemid):
    thisitem = DlogIssue.objects.get(id=itemid)
    if not check_owener_right(request, thisitem):
        setFlash(request, "只有所有者才能修改，请登录")
        return HttpResponseRedirect(stayPreAddress(request))
    yestoday = getLogSomedaySomeUser(DiffWorkDay(date.today(), -1), request.user)
    op = {'yestoday':yestoday, 'today':thisitem, 'page_track_addr':'/dlog/modify/id/'}
    return render_to_response('modify.html', globalRenderOption(request, op))

def do_modify(request, itemid):
    thisitem = DlogIssue.objects.get(id=itemid)
    thisitem.content = request['content']
    thisitem.plan = request['plan']
    thisitem.save()
    return HttpResponseRedirect("/dlog/item/%s" % itemid)

def login(request):
    next = rget(request, 'next', '')
    if request.has_key('user') or request.has_key('password'):
        user = authenticate(username=request['user'], password=request['password'])
        if user is not None:
            if user.is_active:
                django_login(request, user)
                setFlash(request, "成功登录！", True)
                return next and HttpResponseRedirect(next) or HttpResponseRedirect("/blog/")
            else:
                setFlash(request, "登录失败，该帐户已经无效!")
        else:
            setFlash(request, "登录失败，请检查密码是否正确!")
    else:
        next = next and next or stayPreAddress(request)
    return render_to_response('login.html', globalRenderOption(request, {'next':next}))

def logout(request):
    django_logout(request)
    setFlash(request, "成功注销", True)
    return HttpResponseRedirect(stayPreAddress(request))

def search(request):
    issues = DlogIssue.objects.filter(content__contains=request["keyword"])
    setFlash(request, "成功找到%s个结果" % issues.count(), True)
    return render_to_response('list.html', globalRenderOption(request, {'issues':issues}))
    
def today_check(request):
    off = rget(request, 'off', '0')
    t = DiffWorkDay(date.today(), int(off))
    return HttpResponseRedirect("/dlog/dcheck/%s/%s/%s/" % (t.year, t.month, t.day))

def daily_check(request, year, month, day):
    cdate = date(int(year), int(month), int(day))
    tdlogs = getLogsSomeday(cdate)
    groups = Group.objects.all()
    group = rget(request, 'group', None)
    if group:
        users = User.objects.filter(groups__id=group).filter(is_staff=False)
    else:
        users = User.objects.filter(is_staff=False)
    dlogs = [{'user':user, 'log':_getlog_by_user(user, tdlogs)} for user in users]
    op = globalRenderOption(request, {'dlogs':dlogs, 'cdate':cdate, 'groups':groups,
                                      'pre':DiffWorkDay(cdate, -1), 
                                      'next':DiffWorkDay(cdate, 1),
                                      'istoday':cdate==date.today(),
                                      'page_track_addr':'/dlog/dcheck/id/'})
    return render_to_response('dcheck.html', op)

def my_check(request):
    t = date.today()
    user_id = 0
    if check_login_right(request):
        user_id = request.user.id
    else:
        setFlash(request, "请先登录！")
        return HttpResponseRedirect("/dlog/login/?next=%s" % '/dlog/pcheck/')
    return HttpResponseRedirect("/dlog/pcheck/%s/%s/%s/" % (user_id, t.year, t.month))

def people_check(request, user_id, year, month):
    user = User.objects.get(id=user_id)
    cdate = date(int(year), int(month), 1)
    op = {'cdate':cdate, 'users':User.objects.exclude(id=user_id), 'page_track_addr':'/dlog/pcheck/id/'}
    if not user:
        setFlash(request, "没有指定的用户")        
    else:
        op['user'] = user
        udlogs = DlogIssue.objects.filter(create_by__id=user.id)
        dates = monthList(cdate)
        dlogs = [{'date':dt, 'log':_getlog_by_date(dt, udlogs)} for dt in dates]
        op['logs'] = dlogs
    return render_to_response('pcheck.html', globalRenderOption(request, op))

def suggest(request):
    if not check_login_right(request):
        setFlash(request, "请先登录再提改进意见。")
        return HttpResponseRedirect("/dlog/login/?next=%s" % '/dlog/suggest/')
    return render_to_response('suggest.html', globalRenderOption(request, {'next':stayPreAddress(request)}))

def do_suggest(request):
    sug = SysNofifyIssue()
    sug.suggest_by = request.user
    sug.content = request["content"]
    sug.ntype = SysNofifyIssue.TODO
    sug.save()    
    return HttpResponseRedirect(rget(request, 'next', '/dlog/list/'))

def sendreport(request):
    now = datetime.now()
    if IsWorkDay(now.date()):
        bl = getBlackList()
        if not bl:
            createBlackList()
        try_sendreport()
    return HttpResponseRedirect(stayPreAddress(request))

def changepsw(request):
    next = rget(request, 'next', '')
    user = request.user
    if not check_login_right(request):
        setFlash(request, "请先登录。")
        return HttpResponseRedirect("/dlog/login/?next=%s" % '/dlog/changepsw/')
    newpsw = rget(request, 'newpassword', None)
    repsw = rget(request, 'renewpassword', None)
    if newpsw or repsw:
        if newpsw != repsw:
            setFlash(request, "两次密码不一致!")
        else:
            user.set_password(newpsw)
            user.save()
            setFlash(request, "您的密码修改成功", True)
            return next and HttpResponseRedirect(next) or HttpResponseRedirect("/blog/")
    else:
        setFlash(request, "请填写所有的字段修改密码")
        next = next and next or stayPreAddress(request)
    op = {'next':next, 'user':user}
    return render_to_response('changepsw.html', globalRenderOption(request, op))

def comment(request, itemid):
    if not check_login_right(request):
        setFlash(request, "请先登录！")
        return HttpResponseRedirect(stayPreAddress(request))
    item = DlogIssue.objects.get(id=itemid)
    if not item:
        setFlash(request, "没有这条日志存在。")
        return HttpResponseRedirect(stayPreAddress(request))
    content = rget(request, 'content', None)
    if not content:
        setFlash(request, "请填写评论内容！")
    else:
        newCom = CommentIssue()
        newCom.create_by = request.user
        newCom.target = item
        newCom.content = content
        newCom.save()
        return HttpResponseRedirect(stayPreAddress(request))
    
def mytodo(request):
    if not check_login_right(request):
        setFlash(request, "请先登录！")
        return HttpResponseRedirect(stayPreAddress(request))
    log = getLogSomedaySomeUser(DiffWorkDay(date.today(), -1), request.user)
    if not log:
        setFlash(request, "你昨天没有写日志吧！")
        return HttpResponseRedirect(stayPreAddress(request))
    return HttpResponseRedirect("/dlog/item/%s/" % log.id)